namespace Sustainalytics.Portfolios.BL
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Sustainalytics.DataLayer.Shared;
    using Sustainalytics.Entities;

    public enum PortfolioTypes
    {
        All = 0,

        Custom,

        System
    }

    internal class PortfolioDataSourceStrategy
    {
        private readonly
            IDictionary<Type, Tuple<IRepositoryCollection<Portfolio>, IRepositoryCollection<PortfolioDetails>>> _strategies =
                new Dictionary<Type, Tuple<IRepositoryCollection<Portfolio>, IRepositoryCollection<PortfolioDetails>>>();

        public void RegisterRepository(
            Type type, 
            IRepositoryCollection<Portfolio> portfolioRepository, 
            IRepositoryCollection<PortfolioDetails> detailsRepository)
        {
            this._strategies.Add(
                type, 
                new Tuple<IRepositoryCollection<Portfolio>, IRepositoryCollection<PortfolioDetails>>(
                    portfolioRepository, 
                    detailsRepository));
        }

        public ICollection<IRepositoryCollection<Portfolio>> GetPortfolioRepositories(PortfolioTypes? criteria)
        {
            switch (criteria.GetValueOrDefault())
            {
                default:
                case PortfolioTypes.All:
                    return this._strategies.Values.Select(x => x.Item1).ToList();
                case PortfolioTypes.Custom:
                    return new List<IRepositoryCollection<Portfolio>>() { this._strategies[typeof(Portfolio)].Item1 };
                case PortfolioTypes.System:
                    return new List<IRepositoryCollection<Portfolio>>() { this._strategies[typeof(SystemPortfolio)].Item1 };                
            }
        }

        public ICollection<IRepositoryCollection<PortfolioDetails>> GetPortfolioDetailsRepositories(
            PortfolioTypes? criteria)
        {
            switch (criteria.GetValueOrDefault())
            {
                default:
                case PortfolioTypes.All:
                    return this._strategies.Values.Select(x => x.Item2).ToList();
                case PortfolioTypes.Custom:
                    return new List<IRepositoryCollection<PortfolioDetails>>()
                               {
                                   this._strategies[typeof(Portfolio)].Item2
                               };
                case PortfolioTypes.System:
                    return new List<IRepositoryCollection<PortfolioDetails>>()
                               {
                                  this._strategies[typeof(SystemPortfolio)].Item2
                               };                
            }
        }



        public ICollection<Tuple<IRepositoryCollection<Portfolio>, IRepositoryCollection<PortfolioDetails>>> GeRepositories(PortfolioTypes? criteria)
        {
            switch (criteria.GetValueOrDefault())
            {
                default:
                case PortfolioTypes.All:
                    return this._strategies.Values;
                case PortfolioTypes.Custom:
                    return
                        new List<Tuple<IRepositoryCollection<Portfolio>, IRepositoryCollection<PortfolioDetails>>>()
                            {
                                this._strategies[typeof(Portfolio)]
                            };
                case PortfolioTypes.System:
                    return
                        new List<Tuple<IRepositoryCollection<Portfolio>, IRepositoryCollection<PortfolioDetails>>>()
                            {
                               this._strategies[typeof(SystemPortfolio)]
                            };                
            }
        }
    }
}